<!DOCTYPE html>
<html>
<head>
    <title>实验三：函数调用栈模拟演示软件</title>
  <meta charset="UTF-8">
  <!-- import CSS -->
  <link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
  <link rel="stylesheet" href="./common.css">
  <link rel="stylesheet" href="./main.css">
</head>
<body>
  <div id="app">
    <div class="top">
        <span>
            <el-button aria-setsize="mini" @click="clearData">
                清空
            </el-button>
            <el-button aria-setsize="mini" @click="exec">
                执行{{data.label}}函数
            </el-button>
        </span>
        <el-tree
        :data="data"
        show-checkbox
        node-key="id"
        default-expand-all
        :expand-on-click-node="false">
            <span class="custom-tree-node" slot-scope="{ node, data }">
                <span >{{ node.label }}
                </span>
                <span>
                    <el-button
                    type="text"
                    size="mini"
                    @click="showOrDisAppearEditDailog(data)">
                    Edit
                    </el-button>
                    <el-button
                    type="text"
                    size="mini"
                    @click="() => append(data)">
                    Append
                    </el-button>
                    <el-button
                    type="text"
                    size="mini"
                    @click="() => remove(node, data)">
                    Delete
                    </el-button>
                </span>
            </span>
        </el-tree>

        <el-dialog title="修改函数名" :visible.sync="showEditVisible">
              <el-form :model="funNameform">
                <el-form-item label="函数名" label-width="70px">
                  <el-input v-model="funNameform.name" autocomplete="off"></el-input>
                </el-form-item>
              </el-form>
              <div slot="footer" class="dialog-footer">
                <el-button @click="showOrDisAppearEditDailog">取 消</el-button>
                <el-button type="primary" @click="editFunName">确 定</el-button>
              </div>
          </el-dialog>
    </div>
    <div class="box">

        <el-row :gutter="12" class="main">
            <el-col :span="7">
                <el-card class="box-card fl">
                    <span class="title">
                        function stark
                    </span>
                    <div>
                        <ol class="ol">
                            <li class="item" v-for="v in execList">
                                {{v.title}}  {{v.flag? 'in' : 'out'}}
                            </li>
                        </ol>
                    </div>
                </el-card>

            </el-col>
            <el-col :span="10">
                <el-card class="box-card fl">
                    <div class="stark">
                        <div class="funContain">
                            <ul>
                                <li class="item"
                                v-for="it in showFunList">
                                    {{it}}
                                </li>
                            </ul>
                        </div>
                        <div class="btn">
                            <span>
                                {{curShowIndex}} / {{execList.length}}
                            </span>
                            <el-button size="mini" type="primary" icon="el-icon-refresh-left" @click="reNew"></el-button>
                            <el-button size="mini" type="warning" plain @click="preStep">
                                上一步
                            </el-button>
                            <el-button size="mini" type="primary" plain @click="nextStep">
                                下一步
                            </el-button>
                        </div>
                    </div>
                </el-card>

            </el-col>
            
        </el-row>
            
    </div>

  </div>
</body>
  <!-- import Vue before Element -->
  <script src="https://unpkg.com/vue@2/dist/vue.js"></script>
  <!-- import JavaScript -->
  <script src="https://unpkg.com/element-ui/lib/index.js"></script>
  <script>
      let id = 1;

    new Vue({
      el: '#app',
      data: function() {
        const data = [{
            id: 1,
            label: 'main函数',
            children: []
        }];
        return { 
          data: JSON.parse(JSON.stringify(data)),
          showEditVisible: false,
          funNameform: {
            name: ''
          },
          curSelFunId: '',
          execList: [],
          showFunList: [],
          curShowIndex: 0
         }
      },
      watch: {
        data: {
            deep: true,
            handler(old, nnew) {
                this.data = nnew;
                this.exec();
                // 延时图重置
                this.curShowIndex = 0;
            }
        }
      },
      methods: {
        append(data) {
            console.log(data);
            const newChild = { id: id, label: 'test ' + id++, children: []};
            if (!data.children) {
                this.$set(data, 'children', []);
            }
            data.children.push(newChild);
        },

        remove(node, data) {
            const parent = node.parent;
            const children = parent.data.children || parent.data;
            const index = children.findIndex(d => d.id === data.id);
            children.splice(index, 1);
        },

        showOrDisAppearEditDailog(data) {
            this.showEditVisible = !this.showEditVisible;
            if (!data) return
            this.curSelFunId = data.id;
            this.funNameform.name = data.label;
            console.log(this.curSelFunId);
        },
        editFunName() {
            let id = this.curSelFunId, name = this.funNameform.name, p = this.data;
            let arr = [...p];
            while(arr.length) {
                let t = arr.shift();
                console.log(t.id + ' ');
                if (t.id == id) {
                    t.label = name;
                    console.log(this.data);
                    break;
                }
                if (t.children)
                    for (it of t.children) {
                        arr.push(it);
                    }
            }
            this.showOrDisAppearEditDailog()
        },
        clearData() {
            this.data.splice(0, this.data.length);
            this.data.push({
                id: 1, label: 'main函数',children: [] 
            })
        },
        dfsFunTree(cur) {
            console.log(cur);
            if (!cur) return;
            this.execList.push({title: cur.label, flag: 1});
            for (it of cur.children) {
                this.dfsFunTree(it);
            }
            this.execList.push({title: cur.label, flag: 0});
        },
        exec() {
            this.execList.splice(0, this.execList.length);
            // 拿到正确执行顺序
            this.dfsFunTree(this.data[0]);
            
        },
        preStep() {
            if (!this.curShowIndex) return;
            let ind = --this.curShowIndex, list = this.execList, showList = this.showFunList;
            let curItem = list[ind];
            if (curItem.flag) {
                showList.shift();
            }else {
                showList.unshift(curItem.title);
            }
        },
        nextStep() {
            if (this.curShowIndex == this.execList.length) return;
            let ind = this.curShowIndex++, list = this.execList, showList = this.showFunList;
            let curItem = list[ind];
            if (curItem.flag) {
                showList.unshift(curItem.title);
            }else {
                showList.shift();
            }
        },
        reNew() {
            this.curShowIndex = 0;
            this.showFunList.splice(0, this.showFunList.length);
        }
      }
    })
  </script>
</html>